home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / demos / demobook / groups.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  29.6 KB  |  1,098 lines

  1. /*
  2.  * Copyright 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. #include <stdio.h>
  18. #include "exinterfmotif.h"
  19. #include <gl.h>
  20. #include <sys/time.h>
  21. #include "exbookglo.h"
  22. #include "exglobals.h"
  23. #include "exinterf.h"
  24.  
  25. extern struct filestruct *add_file();
  26. extern void remove_file();
  27. extern struct indexlist *add_keyword();
  28. extern struct indexlist *find_keyword();
  29. struct pagestruct *new_pg();
  30.  
  31. /************************************************************
  32. *
  33. * Given the name of a group, find the pointer to that group.
  34. *
  35. ************************************************************/
  36. struct grptmpltstruct *find_group_wi_name(char *name)
  37. {
  38.    struct grptmpltstruct *tmpgrp;
  39.  
  40.    tmpgrp = firstgroup;
  41.    while (tmpgrp != NULL && tmpgrp->nameptr != (struct indexlist*)find_keyword(name))
  42.       tmpgrp = tmpgrp->nextgrp;
  43.  
  44.    return(tmpgrp);
  45. }
  46.  
  47. void do_print(struct grptmpltstruct *grpptr)
  48. {
  49.    struct indexlist *kwrd;
  50.    struct wordlist *wrdptr;
  51.    struct pagestruct *tmppg;
  52.    struct iconstruct *tmpicon;
  53.    int i;
  54.  
  55.    printf("Name %s %d\n",grpptr->nameptr->string, grpptr->nameptr->num);
  56.    printf(" %d pages  %d keywords \n",grpptr->numpages, grpptr->numkey);
  57.    wrdptr = grpptr->keywords;
  58.    printf(" \t keywords: \n");
  59.    for (i = 0; i < grpptr->numkey; i++)
  60.       {
  61.       kwrd = wrdptr->indexptr;
  62.       printf("\t\t%s %d\n",kwrd->string, kwrd->num);
  63.       wrdptr = wrdptr->next;
  64.       }
  65.    tmppg = grpptr->firstpage;
  66.    i = 0;
  67.    while (tmppg != NULL)
  68.       {
  69.       i++;
  70.       printf(" page %d  %d fronticons %d backicons  \n",
  71.           i, tmppg->frontnumicons, tmppg->backnumicons);
  72.       tmppg = tmppg->nextpage;
  73.       }
  74.    printf("    icons: \n");
  75.    tmppg = grpptr->firstpage;
  76.     /* icons are listed in one long list across all pages */
  77.       tmpicon = tmppg->fronticons;
  78.       while (tmpicon != NULL)
  79.          {
  80.          printf("\t\t %s %d %d\n",tmpicon->iconptr->nameptr->string,
  81.                       tmpicon->xposition_ndx, tmpicon->yposition_ndx);
  82.          tmpicon = tmpicon->nexticon;
  83.          }
  84. }
  85.  
  86. /************************************************************
  87. *
  88. * Print out information about the groups.  Used for debugging.
  89. *
  90. ************************************************************/
  91. print_groups(struct grptmpltstruct *grpptr)
  92. {
  93.    struct grptmpltstruct *tmpgrp;
  94.  
  95.    if (grpptr == NULL)
  96.       {
  97.       tmpgrp = firstgroup;
  98.       while (tmpgrp != NULL)
  99.          {
  100.          do_print(tmpgrp);
  101.          tmpgrp = tmpgrp ->nextgrp;
  102.          }
  103.       }
  104.    else
  105.       do_print(grpptr);
  106. }
  107.  
  108. /************************************************************
  109. *
  110. * Restructure the alphabetical group when a demo is added
  111. * to the book or removed from the book.
  112. *
  113. ************************************************************/
  114. group_setup(struct icntmpltstruct *icnptr, struct iconstruct *iconlistptr, struct grptmpltstruct *thisgrp)
  115. {
  116.    struct iconstruct *curicon, *tmplist, *previcon;
  117.    struct iconstruct *grpcuricon, *grpprevicon;
  118.    struct icntmpltstruct *cticn;
  119.    struct grptmpltstruct *grpptr;
  120.    struct pagestruct *tmppg, *newpg;
  121.    int count, tcount;
  122.    float half;
  123.    double theta;
  124.    int newnumpages;
  125.    int x, y;
  126.    int side;
  127.  
  128.    grpptr = thisgrp;
  129.    if (grpptr != NULL)
  130.       {
  131.       if (iconlistptr != NULL || icnptr != NULL)
  132.          {
  133.          side = FRONT;
  134.          if (iconlistptr == NULL)
  135.             {
  136.             cticn = icnptr;
  137.             while (cticn != NULL)
  138.                {
  139.                tmplist = (struct iconstruct *)malloc(sizeof(struct iconstruct) );
  140.                if (iconlistptr == NULL)
  141.                   iconlistptr = tmplist;
  142.                else
  143.                   curicon->nexticon = tmplist;
  144.                curicon = tmplist;
  145.                curicon->nexticon = NULL;
  146.                curicon->iconptr = cticn;
  147.                curicon->ok = cticn->ok;
  148.                cticn = cticn->nexticntmplt; 
  149.                }
  150.             }
  151.          newpg = NULL;
  152.          count = 0;
  153.          tcount = 0;
  154.          curicon = iconlistptr;
  155.          x = 0;
  156.          y = 3;
  157.          grpptr->ok = FALSE;
  158.          tmppg = grpptr->firstpage;
  159.          newnumpages = 1;
  160.          if (side == FRONT)
  161.             grpcuricon = tmppg->fronticons;
  162.          else
  163.             grpcuricon = tmppg->backicons;
  164.          grpprevicon = NULL;
  165.          while (curicon != NULL)
  166.            {
  167.            if (count < ICONLIMIT)
  168.               {
  169.            if (grpcuricon == NULL)
  170.               {
  171.               grpcuricon = (struct iconstruct *)malloc( sizeof(struct iconstruct ));
  172.               grpcuricon->nexticon = NULL;
  173.               if (side == FRONT)
  174.                  {
  175.                  if (tmppg->fronticons == NULL)
  176.                     tmppg->fronticons = grpcuricon;
  177.                  if (grpprevicon != NULL)
  178.                     grpprevicon->nexticon = grpcuricon;
  179.                  }
  180.               else  /* side = back */
  181.                  {
  182.                  if (tmppg->backicons == NULL)
  183.                     tmppg->backicons = grpcuricon;
  184.                  if (grpprevicon != NULL)
  185.                     grpprevicon->nexticon = grpcuricon;
  186.                  }
  187.               }
  188.            }
  189.         else
  190.            {
  191.            if (side == FRONT)
  192.               {
  193.               tmppg->frontnumicons = tcount;
  194.               side = BACK;  /* back */
  195.               if (grpcuricon == NULL)
  196.                  {
  197.                  grpcuricon =(struct iconstruct *)malloc(sizeof(struct iconstruct ));
  198.                  grpcuricon->nexticon = NULL;
  199.                  }
  200.               tmppg->backicons = grpcuricon;
  201.               if (grpprevicon != NULL)
  202.                  grpprevicon->nexticon = grpcuricon;
  203.               x = 4;
  204.               y = 3;
  205.               }
  206.            else  /*  already did the back of the page */
  207.               {
  208.               newnumpages++;
  209.               tmppg->backnumicons = tcount;
  210.               side = FRONT;
  211.               if (tmppg->nextpage == NULL)
  212.                  {
  213.                  newpg = new_pg();
  214.                  tmppg->nextpage = newpg;
  215.                  newpg->prevpage = tmppg;
  216.                  newpg->direction = tmppg->direction;
  217.                  grpptr->lastpage = newpg;
  218.                  }
  219.               tmppg = tmppg->nextpage;
  220.               if (grpcuricon == NULL)
  221.                  {
  222.                  grpcuricon =(struct iconstruct *)malloc(sizeof(struct iconstruct ));
  223.                  grpcuricon->nexticon = NULL;
  224.                  }
  225.               tmppg->fronticons = grpcuricon;
  226.               if (grpprevicon != NULL)
  227.                  grpprevicon->nexticon = grpcuricon;
  228.               x = 0;
  229.               y = 3;
  230.               }
  231.            count = 0;
  232.            tcount = 0;
  233.            }
  234.         grpprevicon = grpcuricon;
  235.         grpcuricon->xposition_ndx = x;
  236.         grpcuricon->yposition_ndx = y;
  237.         grpcuricon->iconptr = curicon->iconptr;
  238.         grpcuricon->ok = curicon->ok;
  239.         if (grpcuricon->ok)
  240.            grpptr->ok = TRUE;
  241.         if (!Hide || curicon->ok)
  242.           {
  243.           if (side == FRONT)
  244.              {
  245.              x++;
  246.              if (x > 4)
  247.                 {
  248.                 y--;
  249.                 x = 0;
  250.                 }
  251.              }
  252.           else
  253.              {
  254.              x--;
  255.              if (x < 0)
  256.                 {
  257.                 y--;
  258.                 x = 4;
  259.                 }
  260.              }
  261.            count++;
  262.            }
  263.         previcon = curicon->nexticon;
  264.         free(curicon);
  265.         curicon = previcon;
  266.         grpcuricon = grpcuricon->nexticon;
  267.         tcount++;
  268.         }  /* endof while curicon */
  269.     grpprevicon->nexticon = NULL;
  270.     if (side == FRONT)
  271.        {
  272.        tmppg->frontnumicons = tcount;
  273.        tmppg->backnumicons = 0;
  274.        tmppg->backicons = NULL;
  275.        }
  276.     else
  277.        tmppg->backnumicons = tcount;
  278.     }
  279.    else  /* icnptr & iconlist == NULL  if I get here  */
  280.       {
  281.       newpg = NULL;
  282.       count = 0;
  283.       tcount = 0;
  284.       x = 0;
  285.       y = 3;
  286.       tmppg = grpptr->firstpage;
  287.       newnumpages = 1;
  288.       side = FRONT;
  289.       grpcuricon = tmppg->fronticons;
  290.       while (grpcuricon != NULL)
  291.          {
  292.          if (count >= ICONLIMIT)
  293.             {
  294.             if (side == FRONT)
  295.                {
  296.                tmppg->frontnumicons = tcount;
  297.                side = BACK;
  298.                tmppg->backicons = grpcuricon;
  299.                if (grpprevicon != NULL)
  300.                   grpprevicon->nexticon = grpcuricon;
  301.                x = 4;
  302.                y = 3;
  303.                }
  304.             else /* side == BACK  */
  305.                {
  306.                newnumpages++;
  307.                tmppg->backnumicons = tcount;
  308.                side = FRONT;
  309.                if (tmppg->nextpage == NULL)
  310.                   {
  311.                   newpg = new_pg();
  312.                   tmppg->nextpage = newpg;
  313.                   newpg->prevpage = tmppg;
  314.                   newpg->direction = tmppg->direction;
  315.                   grpptr->lastpage = newpg;
  316.                   }
  317.                tmppg = tmppg->nextpage;
  318.                tmppg->fronticons = grpcuricon;
  319.                if (grpprevicon != NULL)
  320.                   grpprevicon->nexticon = grpcuricon;
  321.                x = 0;
  322.                y = 3;
  323.                }
  324.             count = 0;
  325.             tcount = 0;
  326.             }  /* end if if count >= ICONLIMIT  */
  327.          grpprevicon = grpcuricon;
  328.          grpcuricon->xposition_ndx = x;
  329.          grpcuricon->yposition_ndx = y;
  330.          if (!Hide || grpcuricon->ok)
  331.            {
  332.            if (side == FRONT)
  333.               {
  334.               x++;
  335.               if (x > 4)
  336.                  {
  337.                  y--;
  338.                  x = 0;
  339.                  }
  340.               }
  341.            else
  342.               {
  343.               x--;
  344.               if (x < 0)
  345.                  {
  346.                  y--;
  347.                  x = 4;
  348.                  }
  349.               }
  350.             count++;
  351.             }
  352.          grpcuricon = grpcuricon->nexticon;
  353.          tcount++;
  354.          }
  355.     if (side == FRONT)
  356.        {
  357.        tmppg->frontnumicons = tcount;
  358.        tmppg->backicons = NULL;
  359.        tmppg->backnumicons = 0;
  360.        }
  361.     else
  362.        tmppg->backnumicons = tcount;
  363.       }
  364.     while (newnumpages < grpptr->numpages)
  365.        {
  366.        grpptr->numpages--;
  367.        tmppg = grpptr->lastpage;
  368.        grpptr->lastpage = tmppg->prevpage;
  369.        tmppg->prevpage = NULL;
  370.        grpptr->lastpage->nextpage = NULL;
  371. /*
  372.        free(tmppg);
  373. */
  374.        }
  375.     grpptr->numpages = newnumpages;
  376.     }
  377. }
  378.  
  379. void setup_all_groups()
  380. {
  381.    struct grptmpltstruct *grpptr;
  382.    struct pagestruct *tmppg;
  383.    Boolean found;
  384.  
  385.    grpptr = firstgroup;
  386.  
  387.    while (grpptr != NULL)
  388.       {
  389.       group_setup(NULL, NULL, grpptr);
  390.       if (grpptr == curgroup && rightpage != grpptr->firstpage)
  391.          {
  392.          found = FALSE;
  393.          tmppg = grpptr->firstpage;
  394.          while (!found && tmppg != NULL)
  395.             {
  396.             if (leftpage == tmppg)
  397.                found = TRUE;
  398.             else
  399.                tmppg = tmppg->nextpage;
  400.             }
  401.          if (!found)
  402.             {
  403.             leftpage = NULL;
  404.             rightpage = grpptr->firstpage;
  405.             }
  406.          else if (leftpage->backicons == NULL)
  407.             {
  408.             rightpage = leftpage;
  409.             leftpage = leftpage->prevpage;
  410.             }
  411.          }
  412.       grpptr = grpptr->nextgrp;
  413.       }
  414. }
  415.  
  416. /************************************************************
  417. *
  418. * Set the view matrix for the part of the group window that
  419. * contains the new page.
  420. *
  421. ************************************************************/
  422. setgroupview()
  423. {
  424.    long winsize_x, winsize_y;
  425.    float xratio, ydif;
  426.  
  427.    getsize(&winsize_x, &winsize_y);
  428.    viewport(0, winsize_x-1, 0, winsize_y -1);
  429.    ortho2(0.0, (float)PGWIDTH, 0.0, (float)PGHEIGHT);
  430. }
  431.  
  432. setgpform(struct grptmpltstruct *grpptr)
  433. {
  434.   struct charlist *curchar, *prevchar;
  435.   struct wordlist *wrdptr;
  436.   struct indexlist *ndxptr;
  437.   int count;
  438.   long cumlength, limit;
  439.   static short nblocks_grp = 1;
  440.  
  441.    if (grpptr != NULL)
  442.       {
  443. /*    Moved init of Exist Keyword List to initgpform */
  444. /*
  445.       ndxptr = Index;
  446.       count = 0;
  447.       ExistKeywordString[0] = '\0';
  448.       strcpy(ExistKeywordString, "");
  449.       while (ndxptr != NULL) {
  450.         count++;
  451.         strcat(ExistKeywordString, (ndxptr->string));
  452.         strcat(ExistKeywordString, ",");
  453.         ndxptr = ndxptr->next;
  454.       }
  455.       ExistKeywordCount = count;
  456. */
  457.  
  458.       AGName.bufpos = strlen(grpptr->nameptr->string);
  459.       strcpy(AGName.buf, grpptr->nameptr->string);
  460.       count = 0;
  461.       GroupKeywordString[0] = '\0';
  462.       strcpy(GroupKeywordString, "");
  463.       wrdptr = grpptr->keywords;
  464.       limit = (512 *nblocks_grp) - 2;
  465.       cumlength = 0;
  466.       while (wrdptr != NULL)
  467.          {
  468.          curchar = (struct charlist *) malloc(sizeof(struct charlist) );
  469.          curchar->str = NULL;
  470.          curchar->next = NULL;
  471.          if (HeadGrpChar == NULL)
  472.             HeadGrpChar = curchar;
  473.          else
  474.             TailGrpChar->next = curchar;
  475.          TailGrpChar = curchar;
  476.          TailGrpChar->indexflag = 1;
  477.          TailGrpChar->str = (char *) malloc(strlen(wrdptr->indexptr->string)+1 );
  478.          strcpy(TailGrpChar->str, wrdptr->indexptr->string) ;
  479.          cumlength+=(strlen(wrdptr->indexptr->string)+1);
  480.          if (cumlength > limit)
  481.             {
  482.             nblocks_grp++;
  483.             GroupKeywordString = (char *)realloc( (void *)GroupKeywordString,
  484.                                        512*nblocks_grp);
  485.             limit = (512 *nblocks_grp) - 2;
  486.             }
  487.          strcat(GroupKeywordString, (wrdptr->indexptr->string));
  488.          strcat(GroupKeywordString, ",");
  489.          count++;
  490.          wrdptr = wrdptr->next;
  491.          }
  492.       GroupKeywordCount = count;
  493.       }
  494. }
  495.  
  496. /************************************************************
  497. *
  498. * Initialize the window for adding a new group.
  499. *
  500. ************************************************************/
  501. void initgroupwin(struct grptmpltstruct *grp)
  502. {
  503.    initgpform();
  504.    setgpform(grp);
  505.    dogroupview();
  506. }
  507.  
  508. struct grptmpltstruct *new_grp()
  509. {
  510.    struct grptmpltstruct *newgrp;
  511.  
  512.    newgrp = (struct grptmpltstruct *) malloc(sizeof(struct grptmpltstruct));
  513.    newgrp->nameptr = NULL;
  514.    newgrp->numpages = 0;
  515.    newgrp->nextgrp = NULL;
  516.    newgrp->prevgrp = NULL;
  517.    newgrp->firstpage = NULL;
  518.    newgrp->lastpage = NULL;
  519.    newgrp->helpfile = NULL;
  520.    newgrp->numkey = 0;
  521.    newgrp->keywords = NULL;
  522.    newgrp->arttype = 0;
  523.    newgrp->covercolor[0] = 1.0;
  524.    newgrp->covercolor[1] = 0.0;
  525.    newgrp->covercolor[2] = 0.0;
  526.    
  527.    return(newgrp);
  528. }
  529.  
  530. struct pagestruct *new_pg()
  531. {
  532.    struct pagestruct *newpg;
  533.  
  534.    newpg = (struct pagestruct *)malloc(sizeof(struct pagestruct) );
  535.    newpg->fronticons = NULL;
  536.    newpg->backicons = NULL;
  537.    newpg->markerptr = NULL;
  538.    newpg->frontnumicons = 0;
  539.    newpg->backnumicons = 0;
  540.    newpg->direction = 1;
  541.    newpg->pgnum = 0;
  542.    newpg->prevpage = NULL;
  543.    newpg->nextpage = NULL;
  544.    
  545.    return(newpg);
  546. }
  547.  
  548. /************************************************************
  549. *
  550. * allocate the new storage for the new group.
  551. *
  552. ************************************************************/
  553. initgroup()
  554. {
  555.    newgrpptr = new_grp();
  556. /* group_setup assumes that there is a first page */
  557.    newgrpptr->firstpage = new_pg();
  558.    newgrpptr->lastpage = newgrpptr->firstpage;
  559.    newgrpptr->lastpage->nextpage = NULL;
  560.  
  561.    curnewpage = newgrpptr->firstpage;
  562.    newgroupiconlist = NULL;
  563.    newgrouplasticon = NULL;
  564.  
  565.     /* for interface */
  566.     AGColor[0] = 1.0;
  567.     AGColor[1] = 0.0;
  568.     AGColor[2] = 0.0;
  569. }
  570.  
  571. /************************************************************
  572. *
  573. * Delete a group.  All of its pages and each page's references
  574. * to icons must also be deleted.
  575. *
  576. ************************************************************/
  577. int deletegroup(struct grptmpltstruct *delgrp)
  578. {
  579.    struct grptmpltstruct *tmpgrp, *tmp2;
  580.    struct pagestruct *pg1, *pg2;
  581.    struct wordlist *wrd1, *wrd2;
  582.    struct iconstruct *tmpicon, *previcon;
  583.    struct grpliststruct *glistptr, *prevglist;
  584.    int i;
  585.    Boolean found;
  586.  
  587. /* need a test to make sure that the
  588.     alphabetical group does not get deleted */
  589.    if (delgrp->nameptr != find_keyword("Master Index"))
  590.       {
  591.       if (delgrp == curgroup)
  592.          {
  593.          DialogType = 3;
  594.          sprintf(msgstring,"%s",delgrp->nameptr->string);
  595.          popup_Question();
  596.          handleMessageEvents();
  597.          if(DeleteGroupFlag != TRUE)
  598.             return(0);
  599.          }
  600.       if (delgrp == firstgroup)
  601.          {
  602.          firstgroup = delgrp->nextgrp;
  603.          firstgroup->prevgrp = NULL;
  604.          }
  605.       else if (delgrp == lastgroup)
  606.          {
  607.          lastgroup = delgrp->prevgrp;
  608.          lastgroup->nextgrp = NULL;
  609.          }
  610.       else
  611.          {
  612.          tmpgrp = delgrp->nextgrp;
  613.          tmpgrp->prevgrp = delgrp->prevgrp;
  614.          tmpgrp = delgrp->prevgrp;
  615.          tmpgrp->nextgrp = delgrp->nextgrp;
  616.          }
  617. /* this stuff will free up all of the pointers
  618.       that had memory allocated for them.  */
  619.       delgrp->nameptr->group = NULL;
  620.       remove_keyword(delgrp->nameptr);
  621.       remove_file(delgrp->helpfile);
  622.       delete_keywords(delgrp, 1);
  623.       pg1 = delgrp->firstpage;
  624.       while (pg1 != NULL)
  625.          {
  626.          pg2 = pg1->nextpage;
  627. /* need to decrement the icon count */
  628.          tmpicon = pg1->fronticons;
  629.          while (tmpicon != NULL)
  630.             {
  631.             (tmpicon->iconptr->occurences)--;
  632.             glistptr = tmpicon->iconptr->grps;
  633.             prevglist = NULL;
  634.             found = FALSE;
  635.             while (glistptr != NULL && !found)
  636.                {
  637.                if (glistptr->grpptr == delgrp)
  638.                   {
  639.                   found = TRUE;
  640.                   if (glistptr == tmpicon->iconptr->grps)
  641.                      tmpicon->iconptr->grps = tmpicon->iconptr->grps->next;
  642.                   else if (glistptr->next == NULL)
  643.                      {
  644.                      if (prevglist != NULL)
  645.                         prevglist->next = NULL;
  646.                      }
  647.                   else
  648.                      {
  649.                      prevglist->next = glistptr->next;
  650.                      }
  651.                   free(glistptr);
  652.                   glistptr = NULL;
  653.                   }
  654.                else
  655.                   {
  656.                   prevglist = glistptr;
  657.                   glistptr = glistptr->next;
  658.                   }
  659.                }
  660.             previcon = tmpicon;
  661.             free(previcon);
  662.             tmpicon = tmpicon->nexticon;
  663.             }
  664.          free(pg1);
  665.          pg1 = pg2;
  666.          }
  667.       tmpgrp = delgrp->nextgrp;
  668.       tmp2 = delgrp->prevgrp;
  669.       if (delgrp == curgroup)
  670.          curgroup = NULL;
  671.       free(delgrp);
  672.       delgrp = NULL;
  673.       rightpage = NULL;
  674.       leftpage = NULL;
  675.       numberofgroups--;
  676.       initbookpos();
  677.       OPENBOOK = FALSE;
  678.       resetshelfcolors();
  679.       if (Indexwin >= 0)
  680.          update_index_win();
  681.       return(1);
  682.       }
  683.    else
  684.       {
  685.       sprintf(msgstring, "The Master Index book can not be deleted.");
  686.       popup_Message();
  687.       return(0);
  688.       }
  689. }
  690.  
  691. /************************************************************
  692. *
  693. * Allows the user to edit the group information.
  694. *
  695. ************************************************************/
  696. long editgroup()
  697. {
  698.    long rslt;
  699.    struct iconstruct *tmpiconlist, *grpicons;
  700.    struct pagestruct *tmppage;
  701.    int i;
  702.    int side;
  703.  
  704.    rslt = -1;
  705.    if (curgroup->nameptr != find_keyword("Master Index"))
  706.       {
  707.       rslt = 1;
  708.       AGColor[0] = curgroup->covercolor[0];
  709.       AGColor[1] = curgroup->covercolor[1];
  710.       AGColor[2] = curgroup->covercolor[2];
  711.       newgrpptr = curgroup;
  712.       curnewpage = newgrpptr->firstpage;
  713.       EditGroupFlag = 1;
  714.       initgroupwin(curgroup);
  715.       /* set name field to group name */
  716.       /* put keywords in the list */
  717.       /* set up list of icons */
  718.       tmppage = curgroup->firstpage;
  719.       while (tmppage != NULL)
  720.          {
  721.          side = FRONT;
  722.          grpicons = tmppage->fronticons;
  723.          newgroupnumicons = tmppage->frontnumicons + tmppage->backnumicons;
  724.          for (i = 0; i < newgroupnumicons; i++)
  725.             {
  726.             tmpiconlist = (struct iconstruct *)malloc(sizeof(struct iconstruct) );
  727.             if (newgroupiconlist == NULL)
  728.                newgroupiconlist = tmpiconlist;
  729.             else
  730.                newgrouplasticon->nexticon = tmpiconlist;
  731.             newgrouplasticon = tmpiconlist;
  732.             tmpiconlist->iconptr = grpicons->iconptr;
  733.             tmpiconlist->ok = grpicons->ok;
  734.             tmpiconlist->xposition_ndx = grpicons->xposition_ndx;
  735.             tmpiconlist->yposition_ndx = grpicons->yposition_ndx;
  736.             tmpiconlist->nexticon = NULL;
  737.             grpicons = grpicons->nexticon;
  738.             if (side == FRONT && grpicons == NULL)
  739.                {
  740.                side = BACK;
  741.                grpicons = tmppage->backicons;
  742.                }
  743.             }
  744.          tmppage = tmppage->nextpage;
  745.          }
  746.       }
  747.    return(rslt);
  748. }
  749.  
  750. /************************************************************
  751. *
  752. * Draw section of the group window that contains the page.
  753. *
  754. ************************************************************/
  755. drawgroupwin()
  756. {
  757.    float x, y;
  758.    struct iconstruct *iconlist;
  759.    float transname;
  760.  
  761.    dogroupview();
  762.    c3s(morecolors[9]);
  763.    clear();
  764. /* drawflaticons here */
  765.    iconlist = newgroupiconlist;
  766.    x = 0.55;
  767.    y = PGHEIGHT - 1.8;
  768.    while (iconlist != NULL)
  769.       {
  770.       transname = -.15;
  771.       pushmatrix();
  772.       translate(x, y, 0.0);
  773.       scale(.7, .7, 1.0);
  774.       if (iconlist->iconptr->poly != NULL)
  775.          drawicon_geom(0, iconlist->iconptr);
  776. /*
  777.       else if (iconlist->iconptr->tex_image != NULL)
  778.          drawicon_img(0,iconlist->iconptr);
  779. */
  780.       else
  781.          transname = 1.125;
  782.       pushmatrix();
  783.       translate(0.0, transname, 0.0);
  784.       draw_demoname(iconlist->iconptr);
  785.       popmatrix();
  786.       popmatrix();
  787.       x = x + 1.5;
  788.       if (x > (PGWIDTH-1.0))
  789.          {
  790.          x = 0.75;
  791.          y = y - 2.0;
  792.          }
  793.       iconlist = iconlist->nexticon;
  794.       }
  795. swapbuffers();
  796. }
  797.  
  798. void pickdrawgroupwin()
  799. {
  800.    short pickname;
  801.    float x, y;
  802.    struct iconstruct *iconlist;
  803.  
  804.    iconlist = newgroupiconlist;
  805.    x = 0.75;
  806.    y = PGHEIGHT - 2.0;
  807.    pickname = 0;
  808.    while (iconlist != NULL)
  809.       {
  810.       loadname(pickname);
  811.       c3s(morecolors[20+pickname]);
  812.       rectf(x, y, x+1.5, y+2.0);
  813.       x = x + 1.5;
  814.       if (x > (PGWIDTH-1.0))
  815.          {
  816.          x = 0.75;
  817.          y = y - 2.0;
  818.          }
  819.       iconlist = iconlist->nexticon;
  820.       pickname++;
  821.       }
  822. }
  823.  
  824. void findicon(float mx, float my, float *ix, float *iy)
  825. {
  826.    int numrows;
  827.    float wy, wx;
  828.  
  829.    numrows = newgroupnumicons/6;  /* 6 = num icons across window */
  830.    wy = (PGHEIGHT - 2.0) - (numrows * 2.0);
  831.    *ix = -1;
  832.    *iy = -1;
  833. }
  834.  
  835. void highlightgroupicon(float ix, float iy)
  836. {
  837. /* already in PUP drawmode */
  838.    dogroupview();
  839.    color(PUP_WHITE);
  840.    rect(ix, iy, ix+1.5, iy+2.0);
  841.  
  842. }
  843.  
  844. /************************************************************
  845. *
  846. * Make sure all of the demos in this group have a pointer
  847. *  back to the group.
  848. *
  849. ************************************************************/
  850. check_demos(struct grptmpltstruct *grpptr)
  851. {
  852.    struct pagestruct *tmppg;
  853.    struct grptmpltstruct *tmpgrp;
  854.    struct grpliststruct *glistptr;
  855.    struct iconstruct *tmpiconptr;
  856.    int i;
  857.    Boolean found;
  858.    int tmpnum, side;
  859.  
  860.    tmppg = grpptr->firstpage;
  861.    while (tmppg != NULL)
  862.       {
  863.       side = FRONT;
  864.       tmpiconptr = tmppg->fronticons;
  865.       tmpnum = tmppg->frontnumicons + tmppg->backnumicons;
  866.       for (i = 0; i < tmpnum; i++)
  867.          {
  868.          found = FALSE;
  869.          glistptr = tmpiconptr->iconptr->grps;
  870.          while (glistptr != NULL && !found)
  871.             {
  872.             if (glistptr->grpptr == grpptr)
  873.                found = TRUE;
  874.             else
  875.                glistptr = glistptr->next;
  876.             }
  877.          if (!found)
  878.             {
  879.             glistptr = (struct grpliststruct *)malloc(sizeof(struct grpliststruct) );
  880.             glistptr->next = NULL;
  881.             glistptr->prev = NULL;
  882.             glistptr->grpptr = grpptr;
  883.             if (tmpiconptr->iconptr->grps == NULL)
  884.                tmpiconptr->iconptr->grps = glistptr;
  885.             else
  886.                {
  887.                glistptr->next = tmpiconptr->iconptr->grps;
  888.                tmpiconptr->iconptr->grps = glistptr;
  889.                }
  890.             }
  891.          tmpiconptr = tmpiconptr->nexticon;
  892.          if (tmpiconptr == NULL && side == FRONT)
  893.             {
  894.             side = BACK;
  895.             tmpiconptr = tmppg->backicons;
  896.             }
  897.          }
  898.       tmppg = tmppg->nextpage;
  899.       }
  900. }
  901.  
  902. void clear_iconlist(struct iconstruct *ic)
  903. {
  904.    struct iconstruct *tmpicon, *previcon;
  905.  
  906.    tmpicon = ic;
  907.    while (tmpicon != NULL)
  908.       {
  909.       previcon = tmpicon;
  910.       tmpicon = tmpicon->nexticon;
  911.       free(previcon);
  912.       }
  913. }
  914.  
  915. void savegroupchanges(struct grptmpltstruct *grpptr)
  916. {
  917.    struct indexlist *tmpptr;
  918.    struct charlist *charptr, *prevcharptr;
  919.    struct wordlist *wrdptr, *twrd;
  920.    int i;
  921.    Boolean indexchange;
  922. struct iconstruct *tmpicon;
  923.  
  924.    indexchange = FALSE;
  925.    grpptr->covercolor[0] = AGColor[0];
  926.    grpptr->covercolor[1] = AGColor[1];
  927.    grpptr->covercolor[2] = AGColor[2];
  928.  
  929.    check_demos(grpptr);
  930.     /* check to see if the name has changed.
  931.     AGName.bufpos will always be > 0 */
  932.    if (strcmp(grpptr->nameptr->string, AGName.buf) != 0)
  933.       {
  934.       indexchange = TRUE;
  935.       tmpptr = grpptr->nameptr;
  936.       if (tmpptr != NULL)
  937.          tmpptr->group = NULL;
  938.       remove_keyword(tmpptr);
  939.       grpptr->nameptr = add_keyword(AGName.buf);
  940.       tmpptr = grpptr->nameptr;
  941.       if (tmpptr != NULL)
  942.          tmpptr->group = grpptr;
  943.       }
  944.  
  945.     /* helpfile */
  946.    if (AGHfile.bufpos <= 0)
  947.       {
  948.       if (grpptr->helpfile != NULL)
  949.          {
  950.          remove_file(grpptr->helpfile);
  951.          grpptr->helpfile = NULL;
  952.          }
  953.       }
  954.    else if (grpptr->helpfile != NULL && (i = strcmp(grpptr->helpfile->name, AGHfile.buf)) != 0)
  955.       {
  956.          {
  957.          remove_file(grpptr->helpfile);
  958.          grpptr->helpfile = add_file(AGHfile.buf);
  959.          }
  960.       }
  961.  
  962.    indexchange = TRUE;
  963.    wrdptr = grpptr->keywords;
  964.    while (wrdptr != NULL)
  965.       {
  966.       remove_keyword_group(wrdptr->indexptr, grpptr);
  967.       twrd = wrdptr;
  968.       wrdptr = wrdptr->next;
  969.       free(twrd);
  970.       }
  971.    grpptr->keywords = NULL;
  972.    charptr = HeadGrpChar;
  973.    i = 0;
  974.    while (charptr != NULL)
  975.       {
  976.       if (grpptr->keywords == NULL)
  977.          {
  978.        grpptr->keywords=(struct wordlist *)malloc(sizeof(struct wordlist));
  979.          grpptr->keywords->indexptr = NULL;
  980.          grpptr->keywords->next = NULL;
  981.          wrdptr = grpptr->keywords;
  982.          }
  983.       else
  984.          {
  985.          wrdptr->next = (struct wordlist *)malloc(sizeof(struct wordlist));
  986.          wrdptr = wrdptr->next;
  987.          wrdptr->next = NULL;
  988.          }
  989.       i++;
  990.       wrdptr->indexptr = add_keyword(charptr->str);
  991.       index_add_group(wrdptr->indexptr, grpptr);
  992.       prevcharptr = charptr->next;
  993.       if (charptr->indexflag == 0)
  994.          free(charptr->str);
  995.       free(charptr);
  996.       charptr = prevcharptr;
  997.       }
  998.    HeadGrpChar = NULL;
  999.    TailGrpChar = NULL;
  1000.    grpptr->numkey = i;
  1001.    group_setup(NULL, newgroupiconlist, grpptr);
  1002. /*
  1003.    clear_iconlist(newgroupiconlist);
  1004. */
  1005.    newgroupiconlist = NULL;
  1006.    newgrouplasticon = NULL;
  1007.  
  1008.    if (indexchange && Indexwin >= 0)
  1009.       update_index_win();
  1010. }
  1011.  
  1012. /************************************************************
  1013. *
  1014. * Add a new group to the book.
  1015. *
  1016. ************************************************************/
  1017. add_group(struct grptmpltstruct *newgrp, struct grptmpltstruct *oldgrp)
  1018. {
  1019.    struct pagestruct *tmppg;
  1020.    struct grptmpltstruct *tmpgrp;
  1021.    int i;
  1022.    float half;
  1023.    double theta;
  1024.    long tmpwin;
  1025.    struct wordlist *wrdptr;
  1026.    struct charlist *charptr, *prevcharptr;
  1027.  
  1028.       numberofgroups++;  /* this is a global variable */
  1029.    initbookpos();
  1030.    check_demos(newgrp);
  1031.    if (newgrp != NULL)
  1032.       {
  1033.       if (oldgrp == lastgroup)
  1034.          {
  1035.          lastgroup->nextgrp = newgrp;
  1036.          newgrp->prevgrp = lastgroup;
  1037.          lastgroup = newgrp;
  1038.          }
  1039.       else
  1040.          {
  1041.          oldgrp->nextgrp = newgrp;
  1042.          newgrp->prevgrp = oldgrp;
  1043.          oldgrp = newgrp;
  1044.          }
  1045.       newgrp->covercolor[0] = AGColor[0];
  1046.       newgrp->covercolor[1] = AGColor[1];
  1047.       newgrp->covercolor[2] = AGColor[2];
  1048.       if (AGName.bufpos == 0)
  1049.          if (HeadGrpChar != NULL)
  1050.             newgrp->nameptr = add_keyword(HeadGrpChar->str);
  1051.          else
  1052.             newgrp->nameptr = add_keyword("unknown");
  1053.       else
  1054.          newgrp->nameptr = add_keyword(AGName.buf);
  1055.       newgrp->nameptr->group = newgrp;
  1056.       if (AGHfile.bufpos > 0)
  1057.          newgrp->helpfile = add_file(AGHfile.buf);
  1058.       charptr = HeadGrpChar;
  1059.       i = 0;
  1060.       while (charptr != NULL)
  1061.          {
  1062.          if (newgrp->keywords == NULL)
  1063.             {
  1064.             newgrp->keywords=(struct wordlist *)malloc(sizeof(struct wordlist));
  1065.             newgrp->keywords->next = NULL;
  1066.             wrdptr = newgrp->keywords;
  1067.             }
  1068.          else
  1069.             {
  1070.             wrdptr->next = (struct wordlist *)malloc(sizeof(struct wordlist));
  1071.             wrdptr = wrdptr->next;
  1072.             wrdptr->next = NULL;
  1073.             }
  1074.          i++;
  1075.          wrdptr->indexptr = add_keyword(charptr->str);
  1076.          index_add_group(wrdptr->indexptr, newgrp);
  1077.          prevcharptr = charptr->next;
  1078.          if (charptr->indexflag == 0)
  1079.             free(charptr->str);
  1080.          free(charptr);
  1081.          charptr = prevcharptr;
  1082.          }
  1083.       HeadGrpChar = NULL;
  1084.       TailGrpChar = NULL;
  1085.       newgrp->numkey = i;
  1086.  
  1087.       group_setup(NULL, newgroupiconlist, newgrp);
  1088. /*
  1089.       clear_iconlist(newgroupiconlist);
  1090. */
  1091.       newgroupiconlist = NULL;
  1092.       newgrouplasticon = NULL;
  1093.       }
  1094.    if (Indexwin >= 0)
  1095.       update_index_win();
  1096. }
  1097.  
  1098.